
#include "cope-timer.h"
#include "cope.h"


void CopeTimer::start(double time) {
    Scheduler &s = Scheduler::instance();
    assert(busy_ == 0);
    
    busy_ = 1;
    paused_ = 0;
    stime_ = s.clock();
    rtime_ = time;
    assert(rtime_ >= 0.0);
    
    s.schedule(this, &event_, rtime_);    
}

void CopeTimer::stop(void) {
    Scheduler &s = Scheduler::instance();
    
    assert(busy_);
    
    if(paused_ == 0)
	s.cancel(&event_);
    
    busy_ = 0;
    paused_ = 0;
    stime_ = 0.0;
    rtime_ = 0.0;
}


/*
 * This function would be called only because of time out.
 * Call the timer's stop() function through parameter Event* e?
 */
void NonAckTimer::handle(Event* e) {
    busy_ = 0;
    paused_ = 0;
    stime_ = 0.0;
    rtime_ = 0.0;

    /*
     * This ?
     */
    cope_->non_ack_handler(e);
}

void NonAckTimer::start(double time) {
    Scheduler &s = Scheduler::instance();
    assert(busy_ == 0);
    
    busy_ = 1;
    paused_ = 0;
    stime_ = s.clock();
    rtime_ = time;
    assert(rtime_ >= 0.0);
    
    s.schedule(this, &event_, rtime_);
}

void NonAckTimer::start(double time, int nodeid, u_int16_t local) {
    nonack_nodeid_ = nodeid;
    nonack_local_seqnum_ = local;
    start(time);
}

void NonAckTimer::stop(void) {
    Scheduler &s = Scheduler::instance();
    
    assert(busy_);
    
    if(paused_ == 0)
	s.cancel(&event_);
    
    busy_ = 0;
    paused_ = 0;
    stime_ = 0.0;
    rtime_ = 0.0;
}

// void NonAckTimer::stop(Packet* p) {
//     Scheduler &s = Scheduler::instance();
//     Event* e = s.lookup(p->uid_);
//     ((CopeTimer*)(e->handler_))->stop(); // maybe problems!!!
// }


CtrlPktTimer::~CtrlPktTimer() {
}

void CtrlPktTimer::handle(Event* e){
  
  stop();
  cope_->ctrl_pkt_handler(this);

}

void CtrlPktTimer::start(double time) {
    if(busy_) {

      //	stop();
      return;

    }

    Scheduler &s = Scheduler::instance();
    assert(busy_ == 0);
    
    busy_ = 1;
    paused_ = 0;
    stime_ = s.clock();
    rtime_ = time;
    assert(rtime_ >= 0.0);
    
    s.schedule(this, &event_, rtime_);    
}

// will stop the timer only if it is busy
void CtrlPktTimer::stop(void) {
    if(!busy_)
    	return;

    Scheduler &s = Scheduler::instance();  
    if(paused_ == 0)
    	s.cancel(&event_);    
    busy_ = 0;
    paused_ = 0;
    stime_ = 0.0;
    rtime_ = 0.0;    
}


